// Copyright (c) 2010 Manuel Peinado Gallego <manuel.peinado@gmail.com>
// Distributed under the MIT license

// ActionShortcuts.cpp : implementation of the Action class
//

#include "stdafx.h"
#include "WorldBuilder.h"
#include "ActionShortcuts.h"
#include "ActionManager.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

void postRemoveAllNodesAction(ActionManager& am, NodeManager& nm)
{
    am.postAction(ref<Action>(
        new RemoveAllNodesAction(nm))
    );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

void postMaterialIdAction(ActionManager& am, ref<MeshBufferInstance> mbi, 
                          ref<Material> newMat, GeometrySide side)
{
    am.postAction(ref<Action>(
        new ShapeMaterialIdAction(mbi, newMat, side))
    );
}

void postShaderIdAction(ActionManager& am, ref<MeshBufferInstance> mbi, 
                        ref<ShaderProgram> prog)
{
    am.postAction(ref<Action>(
        new ShapeShaderIdAction(mbi, prog))
    );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

void postPrimitiveTypeAction(ActionManager& am, ref<GeometryNode> node, 
                            ref<Primitive> newPrim)
{
    am.postAction(ref<Action>(
        new PrimitiveTypeAction(node, newPrim))
    );
}

void postPrimitiveTypeAction(ActionManager& am, ref<GeometryNode> node, 
                             PrimitiveType type)
{
    am.postAction(ref<Action>(
        new PrimitiveTypeAction(node, PrimitiveFactory::primitiveFromType(type)))
    );
}


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

void postShapeWireframeAction(ActionManager& am, ref<MeshBufferInstance> node, 
                                 bool newVal)
{
    am.postAction(ref<Action>(
        new ShapeWireframeAction(node, newVal))
    );

}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

void postTransformNodeAction(
    ActionManager& am, ref<TransformNode> node, const gx::Mat4& newTransform,
    NodeEvent::Property prop)
{
    am.postAction(ref<Action>(
        new TransformNodeAction(node, newTransform, prop))
    );
}

void postTransformNodeAction(
    ActionManager& am, ref<TransformNode> node, const gx::Mat4& newTransform,
    const gx::Mat4& iniTransform, NodeEvent::Property prop)
{
    am.postAction(ref<Action>(
        new TransformNodeAction(node, newTransform, iniTransform, prop))
    );
}

void postMoveNodeAction(ActionManager& am, 
                           ref<TransformNode> node, 
                           const gx::Vec3& offset)
{
    gx::Mat4 m = node->getLocalTransform();
    m.translation += offset;
    postTransformNodeAction(am, node, m, NodeEvent::NodePosition);
}

void postRotateNodeAction(ActionManager& am, 
                             ref<TransformNode> node,
                             const gx::AxisAngle& aa)
{
    gx::Mat4 m = node->getLocalTransform();
    m.rotation = gx::Mat3().make_rot(aa) * m.rotation;
    postTransformNodeAction(am, node, m, NodeEvent::NodeOrientation);
}

void postScaleNodeAction(ActionManager& am, 
                            ref<TransformNode> node,
                            const gx::Vec3& scale)
{
    gx::Mat4 m = node->getLocalTransform();
    m.rotation = gx::Mat3().make_scale(scale) * m.rotation;
    postTransformNodeAction(am, node, m, NodeEvent::NodeScale);
}

void postScaleNodeAction(ActionManager& am, 
                            ref<TransformNode> node,
                            double scale)
{
    gx::Mat4 m = node->getLocalTransform();
    m.rotation = gx::Mat3().make_scale(scale) * m.rotation;
    postTransformNodeAction(am, node, m);
}



// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void postLightParamsAction(ActionManager& am, 
                              ref<LightNode> node, 
                              const LightParams& newParams)
{
    am.postAction(ref<Action>(
        new LightParamsAction(node, newParams))
    );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void postMaterialParamsAction(ActionManager& am, 
                                 ref<Material> node, 
                                 const MaterialParams& newParams)
{
    am.postAction(ref<Action>(
        new MaterialParamsAction(node, newParams))
    );
}

